1   /*
2    * Copyright (c) 2001, 2002, Oracle and/or its affiliates. All rights reserved.
3    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4    *
5    * This code is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU General Public License version 2 only, as
7    * published by the Free Software Foundation.
8    *
9    * This code is distributed in the hope that it will be useful, but WITHOUT
10   * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11   * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12   * version 2 for more details (a copy is included in the LICENSE file that
13   * accompanied this code).
14   *
15   * You should have received a copy of the GNU General Public License version
16   * 2 along with this work; if not, write to the Free Software Foundation,
17   * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18   *
19   * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20   * or visit www.oracle.com if you need additional information or have any
21   * questions.
22   */
23  
24  /**
25   *  @test
26   *  @bug 4451941 4527072
27   *  @summary Test argument types for invoke
28   *
29   *  @author Robert Field
30   *
31   *  @library ..
32   *  @run build  TestScaffold VMConnection TargetListener TargetAdapter
33   *  @run compile -g InvokeTest.java
34   *  @run main InvokeTest
35   */
36  import com.sun.jdi.*;
37  import com.sun.jdi.event.*;
38  import com.sun.jdi.request.*;
39  
40  import java.util.*;
41  
42      /********** target program **********/
43  
44  class InvokeTarg {
45      static InvokeTarg myself = null;
46  
47      boolean[] aBooleanArray = new boolean[] {true, true};
48      byte[] aByteArray = new byte[] {4, 2};
49      char[] aCharArray = new char[] {'k', 'p'};
50      short[] aShortArray = new short[] {55,12, 12};
51      int[] aIntArray = new int[] {6, 3, 1};
52      long[] aLongArray = new long[] {3423423};
53      float[] aFloatArray = new float[] {(float)2.1};
54      double[] aDoubleArray = new double[] {3.141595358979};
55  
56      boolean[][] aBoolean2DArray = new boolean[][]
57                                     {{true, false}, {false, true}};
58      byte[][] aByte2DArray = new byte[][] {{22,66}, {8,9}};
59      char[][] aChar2DArray = new char[][] {{22,66}, {8,9}};
60      short[][] aShort2DArray = new short[][] {{22,66}, {8,9}};
61      int[][] aInt2DArray = new int[][] {{22,66}, {8,9}};
62      long[][] aLong2DArray = new long[][] {{22,66}, {8,9}};
63      float[][] aFloat2DArray = new float[][] {{22,66}, {8,9}};
64      double[][] aDouble2DArray = new double[][] {{22,66}, {8,9}};
65  
66      String[] aStringArray = new String[] {"testing"};
67      String[][] aString2DArray = new String[][]
68                                       {{"hi", "there"}, {"oh"}};
69      Date aDate = new Date();
70      Date[] aDateArray = new Date[] {};
71      Date[][] aDate2DArray = new Date[][] {{}};
72  
73      String aString = "jjxx";
74      long longCheck = 0;
75      boolean booleanCheck = false;
76      boolean voidCheck = false;
77      Object objectCheck = null;
78  
79      public static void main(String[] args){
80          System.out.println("Howdy!");
81          (new InvokeTarg()).sayHi();
82      }
83  
84      void sayHi() {
85      }
86  
87      void checkIn() {
88      }
89  
90      boolean invokeVoid() {
91          voidCheck = true;
92          checkIn();
93          return true;
94      }
95  
96      boolean invokeBoolean(boolean val) {
97          booleanCheck = val;
98          checkIn();
99          return val;
100     }
101 
102     byte invokeByte(byte val) {
103         longCheck = val;
104         checkIn();
105         return val;
106     }
107 
108     char invokeChar(char val) {
109         longCheck = val;
110         checkIn();
111         return val;
112     }
113 
114     short invokeShort(short val) {
115         longCheck = val;
116         checkIn();
117         return val;
118     }
119 
120     int invokeInt(int val) {
121         longCheck = val;
122         checkIn();
123         return val;
124     }
125 
126     long invokeLong(long val) {
127         longCheck = val;
128         checkIn();
129         return val;
130     }
131 
132     float invokeFloat(float val) {
133         longCheck = (long)val;
134         checkIn();
135         return val;
136     }
137 
138     double invokeDouble(double val) {
139         longCheck = (long)val;
140         checkIn();
141         return val;
142     }
143 
144     boolean[] invokeBooleanArray(boolean[] val) {
145         objectCheck = val;
146         checkIn();
147         return val;
148     }
149 
150     byte[] invokeByteArray(byte[] val) {
151         objectCheck = val;
152         checkIn();
153         return val;
154     }
155 
156     char[] invokeCharArray(char[] val) {
157         objectCheck = val;
158         checkIn();
159         return val;
160     }
161 
162     short[] invokeShortArray(short[] val) {
163         objectCheck = val;
164         checkIn();
165         return val;
166     }
167 
168     int[] invokeIntArray(int[] val) {
169         objectCheck = val;
170         checkIn();
171         return val;
172     }
173 
174     long[] invokeLongArray(long[] val) {
175         objectCheck = val;
176         checkIn();
177         return val;
178     }
179 
180     float[] invokeFloatArray(float[] val) {
181         objectCheck = val;
182         checkIn();
183         return val;
184     }
185 
186     double[] invokeDoubleArray(double[] val) {
187         objectCheck = val;
188         checkIn();
189         return val;
190     }
191 
192     boolean[][] invokeBoolean2DArray(boolean[][] val) {
193         objectCheck = val;
194         checkIn();
195         return val;
196     }
197 
198     byte[][] invokeByte2DArray(byte[][] val) {
199         objectCheck = val;
200         checkIn();
201         return val;
202     }
203 
204     char[][] invokeChar2DArray(char[][] val) {
205         objectCheck = val;
206         checkIn();
207         return val;
208     }
209 
210     short[][] invokeShort2DArray(short[][] val) {
211         objectCheck = val;
212         checkIn();
213         return val;
214     }
215 
216     int[][] invokeInt2DArray(int[][] val) {
217         objectCheck = val;
218         checkIn();
219         return val;
220     }
221 
222     long[][] invokeLong2DArray(long[][] val) {
223         objectCheck = val;
224         checkIn();
225         return val;
226     }
227 
228     float[][] invokeFloat2DArray(float[][] val) {
229         objectCheck = val;
230         checkIn();
231         return val;
232     }
233 
234     double[][] invokeDouble2DArray(double[][] val) {
235         objectCheck = val;
236         checkIn();
237         return val;
238     }
239 
240     String invokeString(String val) {
241         objectCheck = val;
242         checkIn();
243         return val;
244     }
245 
246     String[] invokeStringArray(String[] val) {
247         objectCheck = val;
248         checkIn();
249         return val;
250     }
251 
252     String[][] invokeString2DArray(String[][] val) {
253         objectCheck = val;
254         checkIn();
255         return val;
256     }
257 
258     Date invokeDate(Date val) {
259         objectCheck = val;
260         checkIn();
261         return val;
262     }
263 
264     Date[] invokeDateArray(Date[] val) {
265         objectCheck = val;
266         checkIn();
267         return val;
268     }
269 
270     Date[][] invokeDate2DArray(Date[][] val) {
271         objectCheck = val;
272         checkIn();
273         return val;
274     }
275 
276     String invokeCombo(int[][] arr, String val) {
277         objectCheck = val;
278         checkIn();
279         return val;
280     }
281 
282     int[][] invokeCombo2(int[][] val, String str) {
283         objectCheck = val;
284         checkIn();
285         return val;
286     }
287 }
288 
289     /********** test program **********/
290 
291 public class InvokeTest extends TestScaffold {
292     ReferenceType targetClass;
293     ThreadReference mainThread;
294     ObjectReference thisObject;
295     Field longCheckField;
296     Field booleanCheckField;
297     Field voidCheckField;
298     Field objectCheckField;
299     Value longValue;
300     Value booleanValue;
301     Value objectValue;
302     Value voidValue;
303 
304     InvokeTest (String args[]) {
305         super(args);
306     }
307 
308     public static void main(String[] args)      throws Exception {
309         new InvokeTest(args).startTests();
310     }
311 
312     /********** event handlers **********/
313 
314     // not use now
315     public void breakpointReached(BreakpointEvent event) {
316         println("Got BreakpointEvent");
317         longValue = thisObject.getValue(longCheckField);
318         booleanValue = thisObject.getValue(booleanCheckField);
319         objectValue = thisObject.getValue(objectCheckField);
320         voidValue = thisObject.getValue(voidCheckField);
321     }
322 
323     /********** test assist **********/
324 
325     void invoke(Method method, List args, Value value) {
326         Value returnValue = null;
327 
328         try {
329             returnValue = thisObject.invokeMethod(mainThread,
330                                                     method, args, 0);
331         } catch ( Exception ee) {
332             println("Got Exception: " + ee);
333             ee.printStackTrace();
334         }
335         println("        return val = " + returnValue);
336         // It has to be the same value as what we passed in!
337         if (returnValue.equals(value)) {
338             println("         " + method.name() + " return value matches: "
339                     + value);
340         } else {
341             if (value != null) {
342                 failure("FAIL: " + method.name() + " returned: " + returnValue +
343                         " expected: " + value );
344             } else {
345                 println("         " + method.name() + " return value : " + returnValue);
346             }
347 
348         }
349         Value checkValue = (value instanceof PrimitiveValue)?
350                               ((value instanceof BooleanValue)?
351                                         booleanValue : longValue) :
352                               objectValue;
353     }
354 
355 
356     void invoke(String methodName, String methodSig,
357                 List args, Value value)
358         throws Exception {
359         Method method = findMethod(targetClass, methodName, methodSig);
360         if ( method == null) {
361             failure("FAILED: Can't find method: " + methodName  + " for class = " + targetClass);
362             return;
363         }
364         invoke(method, args, value);
365     }
366 
367     void invoke(String methodName, String methodSig, Value value)
368                                            throws Exception {
369         List args = new ArrayList(1);
370         args.add(value);
371         invoke(methodName, methodSig, args, value);
372     }
373 
374 
375     void invoke(String methodName, String methodSig, String fieldName)
376                                            throws Exception {
377         invoke(methodName, methodSig, fieldValue(fieldName));
378     }
379 
380     private Method toStringMethod;
381     Method gettoStringMethod() {
382         if ( toStringMethod != null) {
383             return toStringMethod;
384         }
385 
386         // We have to find it.  First find java.lang.Object
387         List myClasses = vm().allClasses();
388         Iterator iter = myClasses.iterator();
389         ReferenceType objectMirror = null;
390         while (iter.hasNext()) {
391             ReferenceType xx = (ReferenceType)iter.next();
392             if (xx.name().equals("java.lang.Object")) {
393                 objectMirror = xx;
394                 break;
395             }
396         }
397 
398         if (objectMirror == null) {
399             return null;
400         }
401 
402         // Then find toSting
403         List meths = objectMirror.methods();
404         iter = meths.iterator();
405         while (iter.hasNext()) {
406             toStringMethod = (Method)iter.next();
407             if (toStringMethod.name().equals("toString")) {
408                 return toStringMethod;
409            }
410        }
411        toStringMethod = null;
412        return null;
413     }
414 
415     // This calls toString on a field
416     protected void callToString(String fieldName) throws Exception {
417         // Sorry for this kludgy use of global vars.
418         ObjectReference saveObject = thisObject;
419         Method toStringMethod = gettoStringMethod();
420 
421         Field theField = targetClass.fieldByName(fieldName);
422         thisObject = (ObjectReference)thisObject.getValue( theField);
423         invoke(toStringMethod, new ArrayList(0), null);
424         thisObject = saveObject;
425     }
426 
427     Value fieldValue(String fieldName) {
428         Field field = targetClass.fieldByName(fieldName);
429         return thisObject.getValue(field);
430     }
431 
432 
433     /********** test core **********/
434 
435     protected void runTests() throws Exception {
436         /*
437          * Get to the top of sayHi()
438          * to determine targetClass and mainThread
439          */
440         BreakpointEvent bpe = startTo("InvokeTarg", "sayHi", "()V");
441         targetClass = bpe.location().declaringType();
442 
443         mainThread = bpe.thread();
444 
445         StackFrame frame = mainThread.frame(0);
446         thisObject = frame.thisObject();
447         longCheckField = targetClass.fieldByName("longCheck");
448         booleanCheckField = targetClass.fieldByName("booleanCheck");
449         objectCheckField = targetClass.fieldByName("objectCheck");
450         voidCheckField = targetClass.fieldByName("voidCheck");
451         callToString("aBooleanArray");
452 
453         invoke("invokeVoid",    "()Z",  new ArrayList(0), vm().mirrorOf(true));
454 
455         invoke("invokeBoolean", "(Z)Z", vm().mirrorOf(true));
456         invoke("invokeByte",    "(B)B", vm().mirrorOf((byte)14));
457         invoke("invokeChar",    "(C)C", vm().mirrorOf('h'));
458         invoke("invokeShort",   "(S)S", vm().mirrorOf((short)54));
459         invoke("invokeInt",     "(I)I", vm().mirrorOf((int)414));
460         invoke("invokeLong",    "(J)J", vm().mirrorOf((long)140000));
461         invoke("invokeFloat",   "(F)F", vm().mirrorOf((float)315));
462         invoke("invokeDouble",  "(D)D", vm().mirrorOf((double)181818));
463 
464         invoke("invokeBooleanArray",    "([Z)[Z", "aBooleanArray");
465         invoke("invokeByteArray",    "([B)[B", "aByteArray");
466         invoke("invokeCharArray",    "([C)[C", "aCharArray");
467         invoke("invokeShortArray",   "([S)[S", "aShortArray");
468         invoke("invokeIntArray",     "([I)[I", "aIntArray");
469         invoke("invokeLongArray",    "([J)[J", "aLongArray");
470         invoke("invokeFloatArray",   "([F)[F", "aFloatArray");
471         invoke("invokeDoubleArray",  "([D)[D", "aDoubleArray");
472 
473         invoke("invokeBoolean2DArray",    "([[Z)[[Z", "aBoolean2DArray");
474         invoke("invokeByte2DArray",    "([[B)[[B", "aByte2DArray");
475         invoke("invokeChar2DArray",    "([[C)[[C", "aChar2DArray");
476         invoke("invokeShort2DArray",   "([[S)[[S", "aShort2DArray");
477         invoke("invokeInt2DArray",     "([[I)[[I", "aInt2DArray");
478         invoke("invokeLong2DArray",    "([[J)[[J", "aLong2DArray");
479         invoke("invokeFloat2DArray",   "([[F)[[F", "aFloat2DArray");
480         invoke("invokeDouble2DArray",  "([[D)[[D", "aDouble2DArray");
481 
482         invoke("invokeString",    "(Ljava/lang/String;)Ljava/lang/String;",
483                                   vm().mirrorOf("Howdy"));
484         invoke("invokeStringArray",    "([Ljava/lang/String;)[Ljava/lang/String;",
485                                   "aStringArray");
486         invoke("invokeString2DArray",    "([[Ljava/lang/String;)[[Ljava/lang/String;",
487                                   "aString2DArray");
488 
489         invoke("invokeDate",    "(Ljava/util/Date;)Ljava/util/Date;",
490                                   "aDate");
491         invoke("invokeDateArray",  "([Ljava/util/Date;)[Ljava/util/Date;",
492                                   "aDateArray");
493         invoke("invokeDate2DArray", "([[Ljava/util/Date;)[[Ljava/util/Date;",
494                                   "aDate2DArray");
495 
496         Value i2 = fieldValue("aInt2DArray");
497         Value str = vm().mirrorOf("Later");
498         List args = new ArrayList(2);
499         args.add(i2);
500         args.add(str);
501         invoke("invokeCombo",
502                "([[ILjava/lang/String;)Ljava/lang/String;",
503                args, str);
504         invoke("invokeCombo2",
505                "([[ILjava/lang/String;)[[I",
506                args, i2);
507         /*
508          * resume the target listening for events
509          */
510         listenUntilVMDisconnect();
511 
512         /*
513          * deal with results of test
514          * if anything has called failure("foo") testFailed will be true
515          */
516         if (!testFailed) {
517             println("InvokeTest: passed");
518         } else {
519             throw new Exception("InvokeTest: failed");
520         }
521     }
522 }